package cn.gene.timeyan.ums.webapi.ums.service.impl;

import cn.gene.timeyan.common.constant.RedisConstants;
import cn.gene.timeyan.common.exception.TimeyanServiceException;
import cn.gene.timeyan.common.restful.ResponseCode;
import cn.gene.timeyan.pojo.ums.dto.DisturbingDTO;
import cn.gene.timeyan.pojo.ums.dto.UserBindDTO;
import cn.gene.timeyan.ums.service.ISetService;
import cn.gene.timeyan.ums.webapi.ums.mapper.SetMapper;
import cn.gene.timeyan.ums.webapi.ums.mapper.UserMapper;
import cn.gene.timeyan.ums.webapi.ums.utils.EmailUtils;
import cn.gene.timeyan.ums.webapi.ums.utils.RegexUtils;
import cn.gene.timeyan.ums.webapi.ums.utils.UserUtil;
import cn.hutool.core.util.RandomUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * 设置     服务实现类*
 *
 * @author LWG
 * @date 2022/7/22 17:35
 * @since 1.0.0@gene.cn
 */
@Service
public class SetServiceImpl implements ISetService {
    @Autowired
    @Qualifier(value = "redisTemplate1")
    private RedisTemplate redisTemplate;
    @Autowired
    private EmailUtils emailUtils;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserUtil util;
    /**
     * 校验邮箱发送验证码
     * @param userBindDTO
     * @return
     */
    @Override
    public void verifyEmail(UserBindDTO userBindDTO) {
        //校验邮箱
        if (RegexUtils.isEmailInvalid(userBindDTO.getEmail())){
            //邮箱格式不对或为空
            throw new TimeyanServiceException(ResponseCode.ERR_BAD_REQUEST,"邮箱号无效,请输入合法邮箱");
        }
        //生成验证码
        String verificationCode= RandomUtil.randomNumbers(4);
        try{
            emailUtils.sendVerificationCode(userBindDTO.getEmail(),verificationCode);
        }catch (Exception e) {
            //验证码发送失败抛出异常
            throw new TimeyanServiceException(ResponseCode.ERR_UNKNOWN,"啊哦，验证码发送失败，请重新发送");
        }
        //将验证码存入redis并指定过期时间1分钟
        redisTemplate.opsForValue().set(RedisConstants.VERIFY_CODE_KEY +userBindDTO.getEmail(),verificationCode,1, TimeUnit.MINUTES);
    }
    /**
     * 校验手机发送验证码
     * @param userBindDTO
     * @return
     */
    @Override
    public void verifyPhone(UserBindDTO userBindDTO) {
        String phone=userBindDTO.getPhone();
        if (RegexUtils.isPhoneInvalid(phone)){
            //手机格式不对或为空
            throw new TimeyanServiceException(ResponseCode.ERR_BAD_REQUEST,"手机号无效,请输入合法手机号");
        }
        System.out.println(phone);
        //获取发送的验证码
        String code=util.sendValidSms(phone);
        System.out.println(code);
        //将验证码存入redis并指定过期时间1分钟
        redisTemplate.opsForValue().set(RedisConstants.VERIFY_CODE_KEY +phone,code,1, TimeUnit.MINUTES);
    }
    /**
     * 绑定邮箱
     * @param userBindDTO
     * @return
     */
    @Override
    public void bindEmail(UserBindDTO userBindDTO) {
        //验证是否有该用户信息
        if (userBindDTO.getUserId()==null){
            throw new TimeyanServiceException(ResponseCode.NOT_FOUND,"请登录再做此操作");
        }
        String email=userMapper.selectEmailByUserId(userBindDTO.getUserId());
        System.out.println(email);
        if (email!=null&&email.equals(userBindDTO.getEmail())){
            throw new TimeyanServiceException(ResponseCode.ERR_UNIQUE,"该邮箱已绑定");
        }
        //生成key
        String key=RedisConstants.VERIFY_CODE_KEY+userBindDTO.getEmail();
        //当用户输入验证码后确认绑定，先查找该验证码是否过期
        if (!redisTemplate.hasKey(key)){
            System.out.println(redisTemplate.hasKey(key));
            throw new TimeyanServiceException(ResponseCode.ERR_USER_NOT_FOUND,"啊哦，该验证码已过期，请重新发送");
        }
        //该邮箱绑定的验证码还未过期
        String code= (String) redisTemplate.opsForValue().get(key);
        if (userBindDTO.getVerificationCode()==null||!userBindDTO.getVerificationCode().equals(code)){
            //验证码输入值和存储值不同,或验证码输入为null
            System.out.println(userBindDTO.getVerificationCode());
            System.out.println(code);
            throw new TimeyanServiceException(ResponseCode.ERR_BAD_REQUEST,"验证码输入错误，请重新输入");
        }
        //验证无误后存入数据库
        int lines=userMapper.updateEmail(userBindDTO);
        if (lines<1){
            throw new TimeyanServiceException(ResponseCode.ERR_UNKNOWN,"服务器繁忙，绑定失败，请稍后再绑定");
        }
    }

    /**
     * 绑定手机
     * @param userBindDTO
     */
    @Override
    public void bindPhone(UserBindDTO userBindDTO) {
//验证是否有该用户信息
        if (userBindDTO.getUserId()==null){
            throw new TimeyanServiceException(ResponseCode.NOT_FOUND,"请登录再做此操作");
        }
        String phone=userMapper.selectPhoneByUserId(userBindDTO.getUserId());
        System.out.println(phone);
        if (phone!=null&&phone.equals(userBindDTO.getPhone())){
            throw new TimeyanServiceException(ResponseCode.ERR_UNIQUE,"该手机号已绑定");
        }
        //生成key
        String key=RedisConstants.VERIFY_CODE_KEY+userBindDTO.getPhone();
        //当用户输入验证码后确认绑定，先查找该验证码是否过期
        if (!redisTemplate.hasKey(key)){
            System.out.println(redisTemplate.hasKey(key));
            throw new TimeyanServiceException(ResponseCode.ERR_USER_NOT_FOUND,"啊哦，该验证码已过期，请重新发送");
        }
        //该邮箱绑定的验证码还未过期
        String code= (String) redisTemplate.opsForValue().get(key);
        if (userBindDTO.getVerificationCode()==null||!userBindDTO.getVerificationCode().equals(code)){
            //验证码输入值和存储值不同,或验证码输入为null
            System.out.println(userBindDTO.getVerificationCode());
            System.out.println(code);
            throw new TimeyanServiceException(ResponseCode.ERR_BAD_REQUEST,"验证码输入错误，请重新输入");
        }
        //验证无误后存入数据库
        int lines=userMapper.updatePhone(userBindDTO);
        if (lines<1){
            throw new TimeyanServiceException(ResponseCode.ERR_UNKNOWN,"服务器繁忙，绑定失败，请稍后再绑定");
        }
    }
    @Autowired
    SetMapper setMapper;
    @Override
    public void changeState(DisturbingDTO disturbingDTO) {
       Integer rows = setMapper.changeState(disturbingDTO.getUserId(),disturbingDTO.getState());
        if(rows != 1){
            throw new TimeyanServiceException(ResponseCode.ERR_NOTIME,"服务期忙，稍后再试");
        }
    }
}
